<!-- StudyTree.vue -->
<script setup lang="ts">
import { useStudyTreeStore } from '@/stores/useStudyTreeStore'; // 确保路径正确
import { validateNull } from '@/utils/validate';
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { useRoute } from 'vue-router'; // 引入 useRoute
import NodeDetailsComponent from '../../components/NodeDetailsComponent.vue'; // 引入节点详细组件
// import { Position } from "@vue-flow/core";
import { Position, VueFlow } from "@vue-flow/core";
import { Background } from "@vue-flow/background";
import { fetchStudyTreeApi } from '@/api/study/studyTree'; // 引入获取学习树数据的 API
// import { MindMap as TinyMindMap } from '@opentiny/vue';
// 定义接口来描述链接结构
interface Link {
  url: string;
  type: string;
  title: string;
  link: string; // 现在是必需的
}

// 定义接口描述分支节点结构
interface BranchNode {
  links: Link[];
  title: string;
  remark: string;
  status: string;
  description: string;
  branch?: BranchNode[];
}

// 定义接口用于 JSON 内容
interface JsonContentNode {
  [key: string]: BranchNode;
}

// 定义接口用于 MindMap 组件
interface MindMapNode {
  id: string;
  topic: string;
  children: MindMapNode[];
  root?: boolean; // 可选属性
}

// 初始化 mindmapData，包含 nodeData
const mindmapData = ref<{ nodeData: MindMapNode }>({
  nodeData: {
    id: 'root',
    topic: '学习树',
    root: true,
    children: [],
  },
});

// 定义 VueFlow 节点的接口
interface VueFlowNode {
  id: string;
  type: string;
  position: { x: number; y: number };
  data: { label: string; labelNoId?: string };
  sourcePosition?: Position;
  targetPosition?: Position;
}

// 定义 VueFlow 边的接口
interface VueFlowEdge {
  id: string;
  source: string;
  target: string;
  sourceHandle?: string;
}

// 初始化 VueFlow 的 nodes 为一个空数组，为后续从jsonContent中解析数据做准备
const nodes = ref<VueFlowNode[]>([]);

// 初始化 VueFlow 的 edges 为一个空数组，为后续从jsonContent中解析数据做准备
const edges = ref<VueFlowEdge[]>([]);

// 控制 Drawer 的显示状态
const drawerVisible = ref(false);
const selectedNode = ref<{ label: string; details: Link[] }>({ label: '', details: [] });
const route = useRoute(); // 获取路由对象
// const selectedAppId = ref(route.params.id); // 从路由参数获取 id
const selectedAppId = ref<string>(Array.isArray(route.params.id) ? route.params.id[0] : route.params.id);
// 生成唯一 ID 的辅助函数
const generateUniqueId = (): string => {
  return `id-${Math.random().toString(36).substr(2, 9)}`;
};

// 递归解析 JSON 数据，适配 TinyMindMap 组件
const parseJsonToMindMap = (jsonContent: JsonContentNode[]): MindMapNode[] => {
  const isBranchNode = (node: any): node is BranchNode => {
    return node && typeof node === 'object' && 'title' in node;
  };

  const traverse = (nodeData: JsonContentNode | BranchNode): MindMapNode[] => {
    const nodes: MindMapNode[] = [];

    if (typeof nodeData === 'object' && nodeData !== null) {
      if (isBranchNode(nodeData)) {
        const result: MindMapNode = {
          id: generateUniqueId(),
          topic: nodeData.title || '未命名节点',
          children: [],
        };

        if (nodeData.branch && Array.isArray(nodeData.branch)) {
          nodeData.branch.forEach((childNode) => {
            const childNodes = traverse(childNode);
            result.children.push(...childNodes);
          });
        }
        if (validateNull(result.children))
          result.children = []; // 确保 children 为数组

        nodes.push(result);
      }
      else {
        for (const key in nodeData) {
          if (Object.prototype.hasOwnProperty.call(nodeData, key)) {
            const branchNode = nodeData[key];
            nodes.push(...traverse(branchNode));
          }
        }
      }
    }

    return nodes;
  };

  // 开始解析
  const parsedNodes = jsonContent.flatMap(item => traverse(item));
  // console.log('Parsed Nodes:', parsedNodes); // 调试信息
  return parsedNodes;
};

// 查找节点详细信息
const findNodeDetails = (nodeData: JsonContentNode[], targetTopic: string): BranchNode | null => {
  let result: BranchNode | null = null;

  const isBranchNode = (node: any): node is BranchNode => {
    return node && typeof node === 'object' && 'title' in node;
  };

  const traverse = (nodeData: JsonContentNode | BranchNode): void => {
    if (result)
      return;

    if (Array.isArray(nodeData)) {
      nodeData.forEach(item => traverse(item));
    }
    else if (isBranchNode(nodeData)) {
      if (nodeData.title === targetTopic) {
        result = nodeData;
        // console.log('Match found:', nodeData); // 调试信息
        return;
      }
      if (nodeData.branch && Array.isArray(nodeData.branch))
        nodeData.branch.forEach(childNode => traverse(childNode));
    }
    else {
      for (const key in nodeData) {
        if (Object.prototype.hasOwnProperty.call(nodeData, key)) {
          const branchNode = nodeData[key];
          traverse(branchNode);
        }
      }
    }
  };

  nodeData.forEach(item => traverse(item));
  return result;
};

// VueFlow点击节点时处理事件
const onNodeClickFlow = (nodeEvent: any) => {
  const node = nodeEvent.node;

  // 添加检查，防止 node 未定义
  if (!node) {
    console.error('node is undefined in onNodeClickFlow');
    return;
  }

  const nodeLabelNoId = node.data.labelNoId;

  // 添加检查，防止 labelNoId 未定义
  if (!nodeLabelNoId) {
    console.error('labelNoId is undefined in node data');
    return;
  }

  const storedJsonContent = localStorage.getItem('jsonContent');
  // console.log('存储的 JSON 内容:', storedJsonContent); // 调试信息

  if (storedJsonContent) {
    try {
      const jsonContent: JsonContentNode[] = JSON.parse(storedJsonContent);
      // console.log('解析后的 JSON 内容:', jsonContent); // 调试信息
      const nodeDetails = findNodeDetails(jsonContent, nodeLabelNoId);
      // console.log('找到的节点详情:', nodeDetails); // 调试信息

      if (nodeDetails) {
        selectedNode.value = {
          label: nodeLabelNoId,
          details: nodeDetails.links || [], // 查找节点资源详情
        };
        // console.log('设置 selectedNode:', selectedNode.value); // 调试信息
        drawerVisible.value = true;
        // console.log('设置 drawerVisible 为 true'); // 调试信息
      }
      else {
        console.warn('未找到对应主题的节点详情:', nodeLabelNoId); // 调试信息
      }
    }
    catch (error) {
      console.error('解析存储的 JSON 内容时出错:', error);
    }
  }
};

// 将MindMapNode转换为VueFlowNode
const convertMindMapToVueFlowNodes = (mindMapNode: MindMapNode): VueFlowNode[] => {
  // 节点id生成函数
  const generateNodeId = (parentId: string, index: number): string => {
    return parentId ? `${parentId}.${index + 1}` : `${index + 1}`;
  };

  // 节点位置计算函数
  const calculatePosition = (level: number, index: number): { x: number, y: number } => {
    const x = level * 150 + (level === 0 ? 150 : 0); // Main nodes spaced by 300px, child nodes by 150px
    const y = index * 100; // Vertical spacing of 100px
    return { x, y };
  };

  const nodes: VueFlowNode[] = [];

  // 判断是否为整数
  const isInteger = (str: string): boolean => {
    const num = parseInt(str, 10);
    return Number.isInteger(num) && num.toString() === str;
  };

  // 递归遍历MindMapNode生成VueFlowNode
  const traverseMindMap = (node: MindMapNode, parentId = '', level = 0, index = 0): void => {
    const nodeId = generateNodeId(parentId, index);
    const position = calculatePosition(level, index);

    const vueFlowNode: VueFlowNode = {
      id: nodeId,
      type: 'default',
      position,
      data: { label: node.topic || '未命名节点' },
    };

    nodes.push(vueFlowNode);

    if (node.children && Array.isArray(node.children)) {
      node.children.forEach((childNode, childIndex) => {
        traverseMindMap(childNode, nodeId, level + 1, childIndex);
      });
    }
  };

  traverseMindMap(mindMapNode, '', 0, 0);

  // 遍历所有 VueFlow 节点，对每个节点的id整理，如果为1，则替换为root，其他节点的前两个字符删除
  nodes.forEach((node) => {
    if (node.id === '1')
      node.id = 'root';
    else
      node.id = node.id.slice(2);
  });

  // 更新每个节点的属性
  nodes.forEach((node) => {
    if (node.id === 'root') {
      node.position.x = 0;
      node.position.y = 0;
      node.sourcePosition = Position.Right;
      node.targetPosition = Position.Left;
    }
    else {
      // 非root节点，判断是否为一级节点，如果id为一个整数，则为一级节点
      // 一级节点，则x坐标为300*id转换为数字，y坐标为0
      if (isInteger(node.id)) {
        node.position.x = 300 * parseInt(node.id);
        node.position.y = 0;
        node.sourcePosition = Position.Right;
        node.targetPosition = Position.Left;
      }
      else {
        // 非一级节点
        // 确定父节点的x坐标
        // 获取当前节点的index，通过.来分割id，取最后一个元素
        const parts = node.id.split('.');
        const lastPartLen = parts[parts.length - 1].length;
        const parentID = node.id.slice(0, node.id.length - 1 - lastPartLen);
        const parentX = nodes.find(n => n.id === parentID)?.position.x;

        // 获取列表中的前一个节点
        const curIndexInNodes = nodes.findIndex(n => n.id === node.id);
        const previousNode = nodes[curIndexInNodes - 1];
        const previousY = previousNode ? previousNode.position.y : 0;

        node.position.x = parentX ? parentX + 100 : 0;
        // 确定y坐标，为100*id转换为数字
        node.position.y = 70 + previousY;

        node.sourcePosition = Position.Left;
        node.targetPosition = Position.Left;
      }
    }

    // 除了root节点，将id添加在label前面
    if (node.id !== 'root') {
      node.data.labelNoId = node.data.label;
      node.data.label = `${node.id}. ${node.data.label}`;
    }
  });

  return nodes;
};

// 定义一个函数依据nodes生成edges
const generateEdges = (nodes: VueFlowNode[]): VueFlowEdge[] => {
  const edges: VueFlowEdge[] = [];

  const isInteger = (str: string): boolean => {
    const num = parseInt(str, 10);
    return Number.isInteger(num) && num.toString() === str;
  };

  nodes.forEach((node) => {
    // 生成一级节点的edges
    if (isInteger(node.id)) {
      // 找到id小1的节点
      const previousNode = nodes.find(n => n.id === (parseInt(node.id) - 1).toString());

      const edge: VueFlowEdge = {
        id: `edge-${node.id}`,
        target: node.id,
        source: previousNode ? previousNode.id : 'root',
      };
      edges.push(edge);
    }
    else {
      const parts = node.id.split('.');
      const lastPartLen = parts[parts.length - 1].length;
      // 生成非一级节点的edges
      const edge: VueFlowEdge = {
        id: `edge-${node.id}`,
        target: node.id,
        source: node.id.slice(0, node.id.length - 1 - lastPartLen),
        sourceHandle: 'buttom',
      };
      edges.push(edge);
    }
  });

  return edges;
};

// 响应式变量
const isMobile = ref(false);

// 检测是否为移动设备
const updateIsMobile = () => {
  isMobile.value = window.innerWidth <= 768;
};

// 初始缩放比例
const initialZoom = computed(() => {
  return isMobile.value ? 0.6 : 1;
});

// 动态调整 Drawer 宽度
const drawerWidth = computed(() => (isMobile.value ? '100%' : '70%'));

// 动态调整 Drawer 内容样式
const drawerBodyStyle = computed(() => ({
  padding: isMobile.value ? '1rem' : '2rem',
}));

onMounted(async () => {
  // 判断是否是移动端
  updateIsMobile();
  window.addEventListener('resize', updateIsMobile);

  if (selectedAppId.value) {
    try {
      // const response = await api.get('/java/teacher/study_tree_json/detail', { params: { id: selectedAppId.value } });
      const response = await fetchStudyTreeApi({ id: selectedAppId.value });
      if (!response.data || !response.data.jsonContent) {
        console.error('Invalid API response structure:', response.data);
        return;
      }

      const jsonContent: JsonContentNode[] = JSON.parse(response.data.jsonContent);
      const { setJsonContent } = useStudyTreeStore();
      setJsonContent(jsonContent);
      localStorage.setItem('jsonContent', JSON.stringify(jsonContent));

      const parsedMindMap = parseJsonToMindMap(jsonContent);
      mindmapData.value.nodeData.children = parsedMindMap;

      // 根据 mindmapData 的数据生成 VueFlow 的节点
      const parsedVueFlowNodes = convertMindMapToVueFlowNodes(mindmapData.value.nodeData);
      nodes.value = parsedVueFlowNodes;

      // 生成 edges
      edges.value = generateEdges(nodes.value);
    }
    catch (error) {
      console.error('Error fetching study tree:', error);
    }
  }
});

// 清理事件监听
onUnmounted(() => {
  window.removeEventListener('resize', updateIsMobile);
});
</script>

<template>
  <div v-if="!nodes.length" class="loading">
    加载中...
  </div>
  <div v-else class="study-tree-container">
    <VueFlow
      :nodes="nodes"
      :edges="edges"
      class="vue-flow"
      :initial-zoom="initialZoom"
      :min-zoom="0.5"
      :max-zoom="2"
      @node-click="onNodeClickFlow"
    >
      <Background pattern-color="#666" :gap="16" />
    </VueFlow>

    <!-- Drawer 显示点击的节点详情 -->
    <a-drawer
      v-model:open="drawerVisible"
      placement="right"
      :width="drawerWidth"
      :body-style="drawerBodyStyle"
    >
      <NodeDetailsComponent
        v-if="selectedNode.label"
        :label="selectedNode.label"
        :details="selectedNode.details"
      />
    </a-drawer>
  </div>
</template>

<style>
@import "@vue-flow/core/dist/style.css";
@import "@vue-flow/core/dist/theme-default.css";
/* 参考博客：https://blog.csdn.net/RenGJ010617/article/details/140619433 */
/* 官方examples：https://vueflow.dev/examples/ */
.loading {
  text-align: center;
  padding: 2rem;
  font-size: 1.2rem;
  color: #888;
}

.study-tree-container {
  display: flex;
  flex-direction: column;
  height: 100vh; /* Full viewport height */
  width: 100%;
  background-color: #f9f9f9;
  padding: 1rem;

  @media (max-width: 768px) {
    padding: 0.5rem; /* 减少内边距 */
  }
}

.vue-flow {
  flex: 1; /* Take up remaining space */
  width: 100%;
  height: 100%;
  font-size: 1rem; /* 保持文字大小一致 */

  @media (max-width: 768px) {
    height: calc(100vh - 2rem); /* 调整高度，避免溢出 */
    font-size: 0.875rem; /* 保持文字大小一致 */
  }
}
</style>
